package org.sky.sys.controller;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.sky.autoconfigure.SkyProperties;
import org.sky.exception.ServiceException;
import org.sky.sys.entity.SysFile;
import org.sky.sys.service.SysFileService;
import org.sky.sys.util.BspUtils;
import org.sky.sys.util.CriteriaUtils;
import org.sky.sys.util.RequestUtils;
import org.sky.sys.util.page.PageListData;
import org.sky.util.FileTypeUtils;
import org.sky.util.JsonUtils;
import org.sky.util.LogUtils;
import org.sky.util.file.ZipUtils;
import org.sky.util.result.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import tk.mybatis.mapper.entity.Example;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
* @author weifx
* @Title: SysFileController
* @ProjectName platform-core
* @Description: TODO{附件表服务类}
* @date 2019-3-17 17:23:14
* @Version 1.0
*/
@Controller
@RequestMapping(value="/sys/SysFile")
public class SysFileController {
    private final static Logger log = LogUtils.getLogger(SysFileController.class);
    @Autowired
    private SysFileService sysFileService;
    /**
    * 打开附件表页面
    * @return
    */
    @GetMapping(value="/initSysFileListPage")
    public String initSysFileListPage(){
        return "sys/file/sysfilelist";
    }
    /**
    * 附件表分页查询
    * @param request
    * @return
    */
    @PostMapping(value = "/selectSysFileByPage",produces = "application/json;charset=UTF-8")
    public @ResponseBody String selectSysFileByPage(HttpServletRequest request){
        String filter = request.getParameter("filter");
        Map filterMap = JsonUtils.json2map(filter);
        String sortfield=request.getParameter("sortfield");
        int pageNum=Integer.parseInt(request.getParameter("page"));//当前第几页
        int pageSize=Integer.parseInt(request.getParameter("rows"));//每页显示条数
        //组织查询条件
        Example example= new Example(SysFile.class);
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.initFilter(criteria, filterMap);
        if(!StringUtils.isBlank(sortfield)) {
            example.setOrderByClause(sortfield);
        }
        PageListData pageData = sysFileService.selectSysFileByPage(pageNum,pageSize,example);
        return JsonUtils.obj2json(pageData);
    }
    /**
    * 打开附件表新增页面
    * @return
    */
    @GetMapping(value="/initSysFileAddPage")
    public String initSysFileAddPage(){
        return "sys/file/sysfileedit";
    }
    /**
    * 打开附件表编辑页面
    * @return
    */
    @GetMapping(value="/initSysFileEditPage")
    public String initSysFileEditPage(){
        return "sys/file/sysfileedit";
    }
    /**
    * 打开附件表明细页面
    * @return
    */
    @GetMapping(value="/initSysFileDetailPage")
    public String initSysFileDetailPage(){
        return "sys/file/sysfiledetail";
    }
    /**
    * 保存{添加/修改}附件表
    * @param request
    * @return
    */
    @PostMapping(value = "/saveAddEditSysFile",produces = "application/json;charset=UTF-8")
    public @ResponseBody String saveAddEditSysFile(HttpServletRequest request){
        Result result = null;
        try {
            SysFile sysFile = RequestUtils.getEntityBean(request, SysFile.class);
            sysFileService.saveAddEditSysFile(sysFile);
            result = Result.success("保存成功",null,null);
        }catch (ServiceException e){
            result = Result.error("保存失败",e.getMessage(),null);
        }
        return JsonUtils.obj2json(result);
    }
    /**
    * 根据Id查询附件表
    * @param id
    * @return
    */
    @GetMapping(value = "/getSysFileById/{id}",produces = "application/json;charset=UTF-8")
    public @ResponseBody String getSysFileById(
        @PathVariable Long id){
        SysFile bean = sysFileService.getSysFileById(id);
        return JsonUtils.obj2json(bean);
    }
    /**
    * 根据ID删除附件表
    * @param request
    * @return
    */
    @PostMapping(value = "/delSysFile",produces = "application/json;charset=UTF-8")
    public @ResponseBody String delSysFile(HttpServletRequest request){
        Result result= null;
        try {
            String delRows=request.getParameter("delRows");
            List<SysFile> de=JsonUtils.json2list(delRows, SysFile.class);
            sysFileService.delSysFileById(de);
            result = Result.success("删除成功",null,null);
        } catch (ServiceException e) {
            // TODO Auto-generated catch block
            result = Result.error("删除失败",e.getMessage(),null);
        }
        return JsonUtils.obj2json(result);
    }

    /**
     * 打开附件上传页面
     * @return
     */
    @GetMapping(value="/initSysFileUploadPage")
    public String initSysFileUploadPage(){
        return "sys/file/sysfileupload";
    }

    /**
     * 附件上传
     * @param request
     * @return
     */
    @PostMapping(value = "/upLoadFiles",produces = "application/json;charset=UTF-8")
    public @ResponseBody String upLoadFiles(HttpServletRequest request){
        Result result = null;
        try {
            SkyProperties skyPro = BspUtils.getBean(SkyProperties.class);
            Map<String, Object> paramMap = new HashMap();
            List<SysFile> list = new ArrayList<SysFile>();
            String params = request.getParameter("data");
            //附加参数
            paramMap = JsonUtils.json2map(params);
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;
            // 取得request中的所有文件名
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                // 取得上传文件
                MultipartFile attachfile = multiRequest.getFile(iter.next());
                if (attachfile != null) {
                    // 取得当前上传文件的文件名称
                    String fileName = attachfile.getOriginalFilename();
                    // 如果名称不为“”,说明该文件存在，否则说明该文件不存在
                    if (fileName.trim() != "") {
                        // 定义上传路径
                        String path = skyPro.getAttachmentDir()
                                + paramMap.get("bizType") + File.separator
                                + paramMap.get("bizCode") + fileName;
                        File localFile = new File(path);
                        if (!localFile.getParentFile().exists()) {
                            localFile.getParentFile().mkdirs();
                        }
                        attachfile.transferTo(localFile);
                        SysFile att = new SysFile();
                        att.setSize(new Long(attachfile.getSize()));
                        att.setType(attachfile.getContentType());
                        att.setSuffix(fileName.split("\\.")[fileName
                                .split("\\.").length - 1]);
                        att.setPath(path);
                        att.setBizCode((String) paramMap.get("bizCode"));
                        att.setBizType((String) paramMap.get("bizType"));
                        att.setName(attachfile.getOriginalFilename());
                        list.add(att);
                    }
                }
            }
            if(null!=list && !list.isEmpty()) {
                sysFileService.batchInsert(list);
            }
            result = Result.success("上传成功",null,null);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("附件上传失败:{}",e.getMessage());
            result = Result.error("上传失败",e.getMessage(),null);
        }
        return JsonUtils.obj2json(result);
    }

    /**
     * 下载压缩文件
     * @param request
     * @param response
     * @throws Exception
     */
    @PostMapping(value = "/downLoadZipFile",produces = "application/json;charset=UTF-8")
    public void downLoadZipFile(HttpServletRequest request, HttpServletResponse response){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        OutputStream fos = null;
        InputStream fis = null;
        String filerealpath = request.getParameter("filerealpath");
        String zipfile = getFileNameNoEx(filerealpath) + ".zip";
        File downZipFiles = null;
        try {
            ZipUtils.zip(zipfile, "", filerealpath);
            downZipFiles = new File(zipfile);
            fis = new FileInputStream(downZipFiles);
            bis = new BufferedInputStream(fis);
            fos = response.getOutputStream();
            bos = new BufferedOutputStream(fos);
            setFileDownloadHeader(request, response, downZipFiles.getName());
            int byteRead = 0;
            byte[] buffer = new byte[8192];
            while ((byteRead = bis.read(buffer, 0, 8192)) != -1) {
                bos.write(buffer, 0, byteRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文件下载失败:{}",e.getMessage());
        } finally {
            try {
                if(null!=bos){
                    bos.flush();
                    bos.close();
                }
                if(null!=fis) {
                    fis.close();
                }
                if(null!=bis){
                    bis.close();
                }
                if(null!=fos) {
                    fos.close();
                }
                // 删除压缩文件
                if(null!=downZipFiles) {
                    downZipFiles.delete();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 下载未压缩的文件
     * @param request
     * @param response
     * @throws IllegalStateException
     * @throws IOException
     */
    @PostMapping(value = "/downLoadFile",produces = "application/json;charset=UTF-8")
    public void downLoadFile(HttpServletRequest request, HttpServletResponse response){
        InputStream fis = null;
        OutputStream os = null;
        try{
            String path = request.getParameter("filerealpath");
            File file = new File(path);//
            String filename = file.getName();//
            fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);

            response.reset();
            // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名
            setFileDownloadHeader(request, response, filename);
            os = new BufferedOutputStream(response.getOutputStream());
            os.write(buffer);// 输出文件
        }
        catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("文件下载失败:{}",e.getMessage());
        }finally {
            try {
                if(null!=fis) {
                    fis.close();
                }
                if(null!=os) {
                    os.flush();
                }
                if(null!=os) {
                    os.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    /**
     * 获取不带后缀的文件名
     * @param filename
     * @return
     */
    private static String getFileNameNoEx(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length()))) {
                return filename.substring(0, dot);
            }
        }
        return filename;
    }
    /**
     * 设置让浏览器弹出下载对话框的Header. 根据浏览器的不同设置不同的编码格式 防止中文乱码
     *
     * @param fileName
     *            下载后的文件名.
     */
    private static void setFileDownloadHeader(HttpServletRequest request,
                                             HttpServletResponse response, String fileName) {
        try {
            // 中文文件名支持
            String encodedfileName = null;
            String agent = request.getHeader("USER-AGENT");
            if (null != agent && -1 != agent.indexOf("MSIE")) {// IE
                encodedfileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            } else if (null != agent && -1 != agent.indexOf("Mozilla")) {
                encodedfileName = new String(fileName.getBytes("UTF-8"),
                        "iso-8859-1");
            } else {
                encodedfileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            }
            response.setHeader("Content-Disposition", "attachment; filename=\""
                    + encodedfileName + "\"");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 打开查看图片页面
     * @return
     */
    @GetMapping(value="/initSysImageDetailPage/{bizType}/{bizCode}")
    public ModelAndView initSysImageDetailPage(
            @PathVariable String bizType,@PathVariable String bizCode){
        ModelAndView mv = new ModelAndView();
        mv.addObject("bizType",bizType);
        mv.addObject("bizCode",bizCode);
        mv.setViewName("sys/file/sysimagedetail");
        return mv;
    }

    /**
     * 根据业务类型，业务编号查询所有
     * @param bizType
     * @param bizCode
     * @return
     */
    @PostMapping(value="/selectSysFileList/{bizType}/{bizCode}",produces = "application/json;charset=UTF-8")
    public @ResponseBody String selectSysFileList(
            @PathVariable String bizType,@PathVariable String bizCode){
        Example example = new Example(SysFile.class);
        example.createCriteria().andEqualTo("bizType",bizType)
                .andEqualTo("bizCode",bizCode);
        List<SysFile> list = sysFileService.selectSysFile(example);
        return JsonUtils.obj2json(list);
    }
    /**
     * 显示图片
     * @param id
     * @return
     */
    @GetMapping (value = "/viewImage/{id}")
    public ResponseEntity<byte[]> viewImage(@PathVariable Long id) {
        HttpHeaders he = new HttpHeaders();
        byte[] picture =  sysFileService.viewImage(id);
        try {
            FileTypeUtils.FileType imgType = FileTypeUtils.getType(picture);
            switch(imgType.name()){
                case "PNG":
                    he.setContentType(MediaType.IMAGE_PNG);
                    break;
                case "JPG":
                    he.setContentType(MediaType.IMAGE_JPEG);
                    break;
                case "JPEG":
                    he.setContentType(MediaType.IMAGE_JPEG);
                    break;
                case "GIF":
                    he.setContentType(MediaType.IMAGE_GIF);
                    break;
                case "BMP":
                    he.setContentType(MediaType.valueOf("image/bmp"));
                    break;
                default:
                    he.setContentType(MediaType.IMAGE_JPEG);
                    break;
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return new ResponseEntity<>(picture,he, HttpStatus.OK);
    }
    @GetMapping (value = "/viewImage/{bizType}/{bizCode}")
    public ResponseEntity<byte[]> viewImage(@PathVariable String bizType,@PathVariable String bizCode) {
        HttpHeaders he = new HttpHeaders();
        byte[] picture =  sysFileService.viewImage(bizType,bizCode);
        try {
            FileTypeUtils.FileType imgType = FileTypeUtils.getType(picture);
            switch(imgType.name()){
                case "PNG":
                    he.setContentType(MediaType.IMAGE_PNG);
                    break;
                case "JPG":
                    he.setContentType(MediaType.IMAGE_JPEG);
                    break;
                case "JPEG":
                    he.setContentType(MediaType.IMAGE_JPEG);
                    break;
                case "GIF":
                    he.setContentType(MediaType.IMAGE_GIF);
                    break;
                case "BMP":
                    he.setContentType(MediaType.valueOf("image/bmp"));
                    break;
                default:
                    he.setContentType(MediaType.IMAGE_JPEG);
                    break;
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return new ResponseEntity<>(picture,he, HttpStatus.OK);
    }
}